﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using ScintillaNET;
using System.IO;
using System.Globalization;

namespace Editor
{
    public partial class FormDocument : DockContent
    {
        public FormDocument()
        {
            InitializeComponent();
        }

        #region Fields

        private string _filePath;

        #endregion Fields

        #region Properties

        public string FilePath
        {
            get { return _filePath; }
            set { _filePath = value; }
        }

        public Scintilla Scintilla
        {
            get
            {
                return scintilla;
            }
        }

        #endregion Properties


        #region Methods

        protected override string GetPersistString()
        {
            return GetType().ToString() + "*" + FilePath;
        }

        private void AddOrRemoveAsteric()
        {
            if (scintilla.Modified)
            {
                if (!Text.EndsWith(" *"))
                    Text += " *";
            }
            else
            {
                if (Text.EndsWith(" *"))
                    Text = Text.Substring(0, Text.Length - 2);
            }
        }


        private void DocumentForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (Scintilla.Modified)
            {
                // Prompt if not saved
                string message = String.Format(
                    CultureInfo.CurrentCulture,
                    "The _text in the {0} file has changed.{1}{2}Do you want to save the changes?",
                    Text.TrimEnd(' ', '*'),
                    Environment.NewLine,
                    Environment.NewLine);

                DialogResult dr = MessageBox.Show(this, message, Program.Title, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation);
                if (dr == DialogResult.Cancel)
                {
                    // Stop closing
                    e.Cancel = true;
                    return;
                }
                else if (dr == DialogResult.Yes)
                {
                    // Try to save before closing
                    e.Cancel = !Save();
                    return;
                }
            }

            // Close as normal
        }


        public bool Save()
        {
            if (String.IsNullOrEmpty(_filePath))
                return SaveAs();

            return Save(_filePath);
        }


        public bool Save(string filePath)
        {
            using (FileStream fs = File.Create(filePath))
            using (BinaryWriter bw = new BinaryWriter(fs))
                bw.Write(scintilla.RawText, 0, scintilla.RawText.Length - 1); // Omit trailing NULL

            scintilla.Modified = false;
            return true;
        }


        public bool SaveAs()
        {
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                _filePath = saveFileDialog.FileName;
                return Save(_filePath);
            }

            return false;
        }

        public int CalcLineWidth()
        {
            int lineNumWidth = 1;
            int lineCount = scintilla.Lines.Count;

            while (lineCount >= 10)
            {
                lineCount /= 10;
                ++lineNumWidth;
            }

            int pixelWidth = scintilla.NativeInterface.TextWidth(Constants.STYLE_LINENUMBER, "9");

            return 6 + lineNumWidth * pixelWidth;
        }

        private void scintilla_ModifiedChanged(object sender, EventArgs e)
        {
            AddOrRemoveAsteric();
        }


        private void scintilla_StyleNeeded(object sender, StyleNeededEventArgs e)
        {
        }

        private void scintilla_TextDeleted(object sender, TextModifiedEventArgs e)
        {
            scintilla.Margins.Margin0.Width = CalcLineWidth();
        }

        private void scintilla_TextInserted(object sender, TextModifiedEventArgs e)
        {
            scintilla.Margins.Margin0.Width = CalcLineWidth();
        }

        #endregion Methods
    }
}
